
#include "../include/Dlt645FrozenDataParseTask.h"
#include "../include/dlt645def.h"
#include "CLogger.h"
#include "../../common/include/common.h"
#include "../../db/include/CDBManager.h"

#include <string.h>
#include <sstream>

#define  DATAFIELD_MAXLEN           25600    //单帧数据域最长200  *128

CDlt645FrozenDataParseTask::CDlt645FrozenDataParseTask(std::shared_ptr<CConfigManager> ccm, 
                        std::shared_ptr<CMosquittoManager> cmm, 
                        std::list<std::shared_ptr<st_dlt645_frozen_rspdata>> &frozen_rspdata)
{
    m_ccm = ccm;
    m_cmm = cmm;
    m_frozen_rspdata.swap(frozen_rspdata);
}


CDlt645FrozenDataParseTask::~CDlt645FrozenDataParseTask()
{
}

void CDlt645FrozenDataParseTask::run()
{
    uint8_t* pdataField = new uint8_t[DATAFIELD_MAXLEN];
    if (nullptr == pdataField)
    {
        CLogger::getInstance()->LOG_E("CDlt645FrozenDataParseTask::run new memeory error.");
        return;
    }
    
    for (auto itf = m_frozen_rspdata.begin(); itf != m_frozen_rspdata.end(); itf++)
    {
        std::shared_ptr<st_dlt645_frozen_rspdata> pfrozen_rspdata = *itf;
        
        m_points_value.clear();
        for (auto itd = pfrozen_rspdata->lstfrozenDatas.begin(); itd != pfrozen_rspdata->lstfrozenDatas.end(); itd++)
        {
            std::string  cur_di = itd->data_di;
            st_frozen_dataitem stfrozenItem = *itd;
                       
            memset(pdataField, 0, DATAFIELD_MAXLEN);         
            int datafield_len = blockdata_recombine(stfrozenItem, pdataField);
            if (datafield_len>0)
            {
                parse_readingdata_rsp(pfrozen_rspdata->dev_id, pfrozen_rspdata->rule_id, cur_di, pdataField, datafield_len);
            }
        }
        
        ST_FROZEN_GROUP_DATA   stfrozen_groupdata;      
        if (pfrozen_rspdata->pfroken_time_data){
            char str_t[64] = { 0 };
            snprintf(str_t, sizeof(str_t), "%d-%02d-%02dT%02d:%02d:00.000+0800", pfrozen_rspdata->pfroken_time_data[0] + 2000, pfrozen_rspdata->pfroken_time_data[1], pfrozen_rspdata->pfroken_time_data[2],
                            pfrozen_rspdata->pfroken_time_data[3], pfrozen_rspdata->pfroken_time_data[4]);
            stfrozen_groupdata.timestamp = str_t;

            delete []pfrozen_rspdata->pfroken_time_data;
        }
        else{
            stfrozen_groupdata.timestamp = get_uart_timestamp_withms(pfrozen_rspdata->acq_start_time); //正常情况不走这里
        }
        stfrozen_groupdata.timestartgather = get_uart_timestamp_withms(pfrozen_rspdata->acq_start_time);
        stfrozen_groupdata.timeendgather = get_uart_timestamp_withms(pfrozen_rspdata->acq_end_time);
        stfrozen_groupdata.additionalcheck = "112233445566";

        get_frozen_pints(stfrozen_groupdata);

        if (stfrozen_groupdata.lstFrozenPts.size() >0)
        {
            CReportManager::getInstance().push_frozen_data(pfrozen_rspdata->dev_id, pfrozen_rspdata->frozen_type, stfrozen_groupdata);
        }
        else{
            CLogger::getInstance()->LOG_W("CDlt645FrozenDataParseTask::parse data list is 0.");
        }
        
    }

    delete[]pdataField;
     
}

int  CDlt645FrozenDataParseTask::blockdata_recombine(st_frozen_dataitem&  stfrozenItem, uint8_t* pdataField)
{
    if ((stfrozenItem.lstDataItem.size() == 0) || (nullptr == pdataField)) {
        return 0;
    }

    int pre_seq_id = 0;
    int startpos = 0;
    int ioffset = 0;
    int  total_len = 0;

    //先查第一帧，即控制码0x91
    auto itm = stfrozenItem.lstDataItem.begin();
    while (itm != stfrozenItem.lstDataItem.end())
    {
        uint8_t* pdata = itm->pfrozen_data;
        uint8_t code = get_ctrlcode(pdata, itm->data_len);
        if (0 == code) {
            CLogger::getInstance()->LOG_W("CDlt645FrozenDataParseTask-blockdata_recombine:get ctrl code error.");
            return 0;
        }
        if (ENUM_CTRLCODE_READ_METERDATA_ABNORMAL == code){
            CLogger::getInstance()->LOG_W("CDlt645FrozenDataParseTask-blockdata_recombine:data error,ctrl code=%d", code);
            return 0;
        }
        if ((ENUM_CTRLCODE_READ_METERDATA_RSP == code) || (ENUM_CTRLCODE_READ_METERDATA_HAVESUBSEQ_RSP == code))
        {
            int data_len = get_frmdata_len(pdata, itm->data_len, startpos);
            if (data_len > 0)
            {     
                memcpy(pdataField + ioffset, pdata + startpos, data_len);
                total_len += data_len;
                ioffset += data_len;
            }
            delete[] pdata;
            stfrozenItem.lstDataItem.erase(itm);
            break;
        }
        itm++;
    }
    //后续数据
    auto ith = stfrozenItem.lstDataItem.begin();
    while (ith != stfrozenItem.lstDataItem.end())
    {
        uint8_t* pdata = ith->pfrozen_data;
        uint8_t code = get_ctrlcode(pdata, ith->data_len);
        if (0 == code) {
            CLogger::getInstance()->log_w("CDlt645FrozenDataParseTask-blockdata_recombine:get ctrl code error.");
            return 0;
        }
        if (ENUM_CTRLCODE_READ_METERDATA_ABNORMAL == code){
            CLogger::getInstance()->log_w("CDlt645FrozenDataParseTask-blockdata_recombine:data error,ctrl code=%d", code);
            ith++;
            continue;;
        }
        if (ENUM_CTRLCODE_READ_SUBSEQDATA_HAVESUBSEQ_RSP == code)
        {
            //帧序号判断，拼接数据
            int seq_id = get_seqid(pdata, ith->data_len);
            if (seq_id == pre_seq_id + 1)   //帧序号为上一帧+1
            {
                int data_len = get_frmdata_len(pdata, ith->data_len, startpos);
                if (data_len > 0)
                {
                    memcpy(pdataField + ioffset, pdata + startpos, data_len);
                    total_len += data_len;
                    ioffset += data_len;
                    pre_seq_id = seq_id;  
                }
                delete[] pdata;
                stfrozenItem.lstDataItem.erase(ith);
                continue;
            }
        }
        ith++;
    }

    //最后一帧
    auto itz = stfrozenItem.lstDataItem.begin();
    while (itz != stfrozenItem.lstDataItem.end())
    {
        uint8_t* pdata = itz->pfrozen_data;
        uint8_t code = get_ctrlcode(pdata, itz->data_len);
        if (0 == code) {
            CLogger::getInstance()->LOG_W("CDlt645FrozenDataParseTask-blockdata_recombine:get ctrl code error.");
            return 0;
        }
        if (ENUM_CTRLCODE_READ_METERDATA_ABNORMAL == code){
            CLogger::getInstance()->LOG_W("CDlt645FrozenDataParseTask-blockdata_recombine:data error,ctrl code=%d", code);
            itz++;
            continue;;
        }

        if (ENUM_CTRLCODE_READ_SUBSEQDATA_RSP == code)
        {
            int data_len = get_frmdata_len(pdata, itz->data_len, startpos);
            if (data_len > 0)
            {
                memcpy(pdataField + ioffset, pdata + startpos, data_len);
                total_len += data_len;
                ioffset += data_len;     
            }
            delete[] pdata;
            stfrozenItem.lstDataItem.erase(ith);
            break;;
        }
    }

    return total_len;
}

int  CDlt645FrozenDataParseTask::parse_readingdata_rsp(int64_t  devid, int64_t rule_id, const std::string& di, uint8_t* pdata, int len)
{
    auto rulesPtr = m_ccm->get_dlt645_rule_points(); //<ruleid,<pointid,pointid>>
    if (nullptr == rulesPtr)
    {
        CLogger::getInstance()->log_d("parse_readingdata_rsp: No rule points.");
        return -1;
    }
    auto rule = rulesPtr->find(rule_id);  //<pointid,pointid>
    if (rule == rulesPtr->end())
    {
        CLogger::getInstance()->log_d("parse_readingdata_rsp: Not find rule point(id=%lld).", rule_id);
        return -1;
    }

    OutputData("CDlt645FrozenDataParseTask::parse_readingdata_rsp=", pdata, len);

    //dlt645模型信息
    std::shared_ptr <T_DLT645_POINT_TYPE> points = m_ccm->get_dlt645_points();

    std::string strval;
    int blk_id = 0;     //块号
    int offset = 0;
    int blk_num = 0;
    //遍历查询总块数
    for (auto pointid = rule->second.begin(); pointid != rule->second.end(); pointid++)
    {
        auto dlt645pt = m_ccm->get_dlt645_point(pointid->first);
        if (nullptr == dlt645pt)
        {
            CLogger::getInstance()->log_w("parse_readingdata_rsp: get dlt645point error.");
            return -1;
        }
        if (dlt645pt->block_no == blk_num)
        {
            blk_num++;
        }
    }
    int* pblk_len = new int[blk_num + 1];
    if (nullptr == pblk_len){
        CLogger::getInstance()->log_w("parse_readingdata_rsp: new int error.");
        return -1;
    }

    while (offset < len)
    {
        bool bfind = false;
        //以块号为轴线，遍历点表、解析数据
        for (auto pointid = rule->second.begin(); pointid != rule->second.end(); pointid++)
        {
            auto dlt645pt = m_ccm->get_dlt645_point(pointid->first);
            if (dlt645pt->pos + dlt645pt->data_size > dlt645pt->block_size) //超出本块的长度
            {
                CLogger::getInstance()->LOG_W("CDlt645FrozenDataParseTask,parse_readingdata_rsp: para error point id=%lld", dlt645pt->id);
                return -1;
            }
            if ((dlt645pt->block_no == blk_id) && (dlt645pt->di.compare(di) == 0))
            {
                bfind = true;
                pblk_len[blk_id] = dlt645pt->block_size;

                //数据类型及长度
                auto dlt645_dataty = m_ccm->get_dlt645_data_type(dlt645pt->data_type);
                int data_size = dlt645_dataty->size;
                if (0 == data_size)
                {
                    CLogger::getInstance()->LOG_W("parse_readingdata_rsp: datasize is 0.");
                    return -1;
                }

                //按编码格式分类
                if (dlt645pt->encode == ENUM_645_ENCODE_BCD)    //BCD码
                {
                    if (dlt645pt->data_type == ENUM_645_DATATYPE_DATETIME)
                    {
                        strval = get_point_val(pdata + offset + dlt645pt->pos, data_size);
                        strval = get_datatime_val(pdata + offset, data_size, dlt645pt->datetime_format);
                    }
                    else if (dlt645pt->data_type == ENUM_645_DATATYPE_STRING)
                    {
                        strval = get_point_val(pdata + offset + dlt645pt->pos, data_size);
                    }
                    else{
                        strval = get_point_val(pdata + offset + dlt645pt->pos, data_size);
                        strval = get_final_val(dlt645pt, strval);
                    }
                    save_point_value(dlt645pt->id, dlt645pt->name, strval);
                }
                else if (dlt645pt->encode == ENUM_645_ENCODE_HEX)  //十六进制---不处理字符串和日期型
                {
                    switch (dlt645pt->data_type)
                    {
                    case ENUM_645_DATATYPE_CHAR:
                        strval = get_final_val_ex<char>(dlt645pt, get_decimal_value<char>(dlt645pt, pdata + offset + dlt645pt->pos));
                        break;
                    case ENUM_645_DATATYPE_UNSIGNED_CHAR:
                        strval = get_final_val_ex<unsigned char>(dlt645pt, get_decimal_value<unsigned char>(dlt645pt, pdata + offset + dlt645pt->pos));
                        break;
                    case ENUM_645_DATATYPE_SHORT:
                        strval = get_final_val_ex<short>(dlt645pt, get_decimal_value<short>(dlt645pt, pdata + offset + dlt645pt->pos));
                        break;
                    case ENUM_645_DATATYPE_UNSIGNED_SHORT:
                        strval = get_final_val_ex<unsigned short>(dlt645pt, get_decimal_value<unsigned short>(dlt645pt, pdata + offset + dlt645pt->pos));
                        break;
                    case ENUM_645_DATATYPE_INT:
                        strval = get_final_val_ex<int>(dlt645pt, get_decimal_value<int>(dlt645pt, pdata + offset + dlt645pt->pos));
                        break;
                    case ENUM_645_DATATYPE_UNSIGNED_INT:
                        strval = get_final_val_ex<unsigned int>(dlt645pt, get_decimal_value<unsigned int>(dlt645pt, pdata + offset + dlt645pt->pos));
                        break;
                    case ENUM_645_DATATYPE_FLOAT:
                        strval = get_final_val_ex<float>(dlt645pt, get_decimal_value<float>(dlt645pt, pdata + offset + dlt645pt->pos));
                        break;
                    case ENUM_645_DATATYPE_DOUBLE:
                        strval = get_final_val_ex<double>(dlt645pt, get_decimal_value<double>(dlt645pt, pdata + offset + dlt645pt->pos));
                        break;
                    case ENUM_645_DATATYPE_DATETIME:
                        strval = get_datatime_val(pdata + offset, data_size, dlt645pt->datetime_format);
                        break;
                    case ENUM_645_DATATYPE_STRING:
                        strval = get_hex_str(dlt645pt, pdata + offset + dlt645pt->pos);
                        break;
                    default:
                        break;
                    }
                    save_point_value(dlt645pt->id, dlt645pt->name, strval);

                }
                else{
                    CLogger::getInstance()->LOG_W("parse_readingdata_rsp dataencode error,not recognition.");
                    continue;
                }                
            }
        }    
        if (bfind)
        {
            offset += pblk_len[blk_id];   //块偏移量
            blk_id++;    //循环外块序号计数再增加，可以解析同一个块内偏移量不同的数据项
        }
        //for 循环中没有一个匹配的di，跳出
        else
        {
            if (offset > 0) {
                CLogger::getInstance()->LOG_W("parse_readingdata_rsp: data field length > prase length, di=%s.", di.c_str());
            }
            else{
                CLogger::getInstance()->LOG_W("parse_readingdata_rsp: data error,can't matching di=%s.", di.c_str());
            }
            break;
        }
    }
    delete[]pblk_len;


    return 0;
}


//获取控制吗，若帧错误返回0
uint8_t CDlt645FrozenDataParseTask::get_ctrlcode(uint8_t* pdata, int len)
{
    uint8_t ctrlcode = 0;
    int prefix_num = verify_dlt645_frame(pdata, len);

    if (prefix_num < 0)
    {
        CLogger::getInstance()->LOG_D("get_ctrlcode: frame error.");
        return ctrlcode;
    }

    ctrlcode = pdata[prefix_num + 8];

    return ctrlcode;
}


//获取数据域中，数据的长
int CDlt645FrozenDataParseTask::get_frmdata_len(uint8_t* pdata, int len, int& startpos)
{
    startpos = 0;
    int prefix_num = verify_dlt645_frame(pdata, len);
    if (prefix_num < 0)
    {
        return 0;
    }

    int data_len = 0;
    uint8_t ctrlcode = get_ctrlcode(pdata, len);
    if ((ENUM_CTRLCODE_READ_METERDATA_HAVESUBSEQ_RSP == ctrlcode) || (ENUM_CTRLCODE_READ_METERDATA_RSP == ctrlcode)) {
        data_len = pdata[prefix_num + 9] - 4;  //减去数据标识长   
        startpos = prefix_num + 14;
    }
    else if ((ENUM_CTRLCODE_READ_SUBSEQDATA_RSP == ctrlcode) || (ENUM_CTRLCODE_READ_SUBSEQDATA_HAVESUBSEQ_RSP == ctrlcode)) {
        data_len = pdata[prefix_num + 9] - 5;  //减去数据标识和帧序号长
        startpos = prefix_num + 14;
    }

    CLogger::getInstance()->log_d("CDlt645FrozenDataParseTask::get_frmdata_len: len=%d", data_len);

    return data_len;
}

std::string CDlt645FrozenDataParseTask::get_point_val(uint8_t* pdata, int bytenum)
{
    std::string  val = "";
    if ((nullptr == pdata) || (0 >= bytenum)){
        return val;
    }

    OutputData("get_point_val data", pdata, bytenum);

    uint8_t byteval = 0;
    int l = bytenum * 2 + 1;
    char buf[l] = { 0 };
    for (int i = bytenum - 1; i >= 0; i--)
    {
        byteval = pdata[i] - FLAG_ERRIDENT;
        sprintf(buf, "%02X", byteval);
        val += buf;
    }
    return val;
}
std::string CDlt645FrozenDataParseTask::get_point_val2(uint8_t* pdata, int bytenum)
{
    std::string  val = "";
    if ((nullptr == pdata) || (0 >= bytenum)){
        return val;
    }

    OutputData("get_point_val2 data", pdata, bytenum);

    uint8_t byteval = 0;
    int l = bytenum * 2 + 1;
    char buf[l] = { 0 };
    for (int i = 0; i < bytenum; i++)
    {
        byteval = pdata[i] - FLAG_ERRIDENT;
        sprintf(buf, "%02X", byteval);
        val += buf;
    }

    return val;
}
std::string CDlt645FrozenDataParseTask::get_final_val(std::shared_ptr<DLT645_POINT> pt, const std::string& val)
{
    if ((nullptr == pt) || val.empty())
    {
        return "";
    }

    char ret_buf[64] = { 0 };
    char str_format[32] = { 0 };
    double fVal = 0.0f;
    std::string  formula = pt->formula;

    CLogger::getInstance()->log_d("645FrozenDataParseTask::get_final_val:val=%s,formula=%s,scale=%f,decimal=%d", val.c_str(), formula.c_str(), pt->scale, pt->decimal);

    trimstring(formula);
    if (formula.empty())
    {
        try{
            fVal = std::stod(val);
        }
        catch (...){
            fVal = std::stod("0x" + val);
        }
        fVal *= pt->scale;
    }
    else{
        std::string formula = "echo \"" + pt->formula + "\"|bc";
        formula = string_replace(formula, "X", val);
        if (0 == exec_cmd((char *)formula.c_str(), ret_buf, sizeof(ret_buf))){
            fVal = atof(ret_buf);
        }
    }

    if (0 < pt->decimal){
        snprintf(str_format, sizeof(str_format), "%%.%dlf", pt->decimal);
        snprintf(ret_buf, sizeof(ret_buf), str_format, fVal);
    }
    else {
        snprintf(ret_buf, sizeof(ret_buf), "%.0f", fVal);
    }
    std::string fina_val(ret_buf);

    {
        CLogger::getInstance()->log_d("get_final_val:fval=%f,fmt=%s,retbuf=%s", fVal, str_format, ret_buf);
    }

    return fina_val;
}

std::string  CDlt645FrozenDataParseTask::get_datatime_val(uint8_t* pdata, int bytenum, const std::string& strfmt)
{
    std::string  strval = strfmt;
    char fmtdata[16] = { 0 };
    char rpstr[12][8] = { "yyyy", "YYYY", "YY", "yy", "MM", "DD", "dd", "WW", "HH", "hh", "mm", "ss" };
    char substr[8] = { 0 };
    int num = 0, idx = -1;

    for (int i = 0; i < 12; i++) {
        strncpy(substr, rpstr[i], 8);
        std::string::size_type pos = strval.find(substr);
        if (pos != std::string::npos){
            if (num < bytenum){
                sprintf(fmtdata, "%02X", pdata[bytenum - num - 1] - FLAG_ERRIDENT); //数据域中的数据为倒序
            }
            else{
                strncpy(fmtdata, "00", sizeof(fmtdata));
            }
            idx = (int)pos;
            strval.replace(idx, strlen(substr), fmtdata);
            num++;
        }
    }

    return strval;
}

int CDlt645FrozenDataParseTask::save_point_value(int64_t point_id, const std::string& name, const std::string& value)
{   
    ST_FROZEN_RPT_DATAPT data;
    data.name = name;
    data.val = value;

    auto pv = m_points_value.find(point_id);
    if (pv == m_points_value.end()){
        m_points_value.insert(std::make_pair(point_id, data));
    }
    else{
        m_points_value[point_id] = data;
    }
    CLogger::getInstance()->log_d("CDlt645FrozenDataParseTask::save_point_value:id=%lld,dataname=%s,val=%s", point_id, name.c_str(), value.c_str());
  
    return 0;
}

void CDlt645FrozenDataParseTask::get_frozen_pints(ST_FROZEN_GROUP_DATA& stfrozenGroupdata)
{
    for (auto itp = m_points_value.begin(); itp != m_points_value.end(); itp++)
    {
        ST_FROZEN_RPT_DATAPT datapt ;
        datapt.name = itp->second.name;
        datapt.val = itp->second.val;

        stfrozenGroupdata.lstFrozenPts.push_back(datapt);
    }
}

//dlt645帧校验，正确是返回前导符个数，错误返回 <0
int  CDlt645FrozenDataParseTask::verify_dlt645_frame(uint8_t* pdata, int len)
{
    int prefix_num = 0;
    if ((MIN_FRAME_LEN > len) || (!pdata)){
        CLogger::getInstance()->LOG_W("CDlt645FrozenDataParseTask::verify_dlt645_frame,frame len error or data is null");
        return -1;
    }

    for (int i = 0; i < 4; i++) {
        if (CHR_PREFIX == pdata[i])
        {
            prefix_num++;
        }
    }
    if ((CHR_FRMSTART != pdata[prefix_num]) || (CHR_FRMSTART != pdata[prefix_num + 7]))
    {
        CLogger::getInstance()->LOG_W("CDlt645FrozenDataParseTask::verify_dlt645_frame,frame header error.");
        return -2;
    }

    uint8_t cscode = CalcCSVal(pdata + prefix_num, len - 2 - prefix_num);
    if (cscode != pdata[len - 2])
    {
        CLogger::getInstance()->LOG_W("CDlt645FrozenDataParseTask::verify_dlt645_frame,У�������.");
        return -4;
    }

    if (pdata[len - 1] != CHR_FRMEND)
    {
        CLogger::getInstance()->LOG_W("CDlt645FrozenDataParseTask::verify_dlt645_frame,frame tail error.");
        return -3;
    }

    return prefix_num;
}

//校验码计算
uint8_t CDlt645FrozenDataParseTask::CalcCSVal(uint8_t* pData, int iLen)
{
    unsigned char CS = 0;
    unsigned int uiVal = 0;
    int i = 0;

    for (i = 0; i < iLen; i++)
    {
        uiVal += pData[i];
    }

    CS = uiVal % 256;

    return CS;
}
//空格字符串，清空
void CDlt645FrozenDataParseTask::trimstring(std::string & str)
{
    size_t s = str.find_first_not_of(" ");
    size_t e = str.find_last_not_of(" ");
    if ((s == std::string::npos) && (e == std::string::npos)){
        str.clear();
    }
}

void CDlt645FrozenDataParseTask::OutputData(const char* pName, uint8_t* pData, int len)
{
    char  szInfo[512] = { 0 };
    char  szch[8] = { 0 };
    for (int i = 0; i < len; i++){
        sprintf(szch, "%02X ", pData[i]);
        strcat(szInfo, szch);
    }

    CLogger::getInstance()->log_d("%s:%s", pName, szInfo);
}

template<typename T>
T CDlt645FrozenDataParseTask::get_decimal_value(std::shared_ptr<DLT645_POINT> pt, uint8_t* pdata)
{
    if (nullptr == pdata){
        return 0;
    }
    uint8_t bytedata[16] = { 0 };
    int bytenum = 0;
    switch (pt->data_type)
    {
    case ENUM_645_DATATYPE_SHORT:
    case ENUM_645_DATATYPE_UNSIGNED_SHORT:
        bytenum = 2;
        break;
    case ENUM_645_DATATYPE_INT:
    case ENUM_645_DATATYPE_UNSIGNED_INT:
    case ENUM_645_DATATYPE_FLOAT:
        bytenum = 4;
        break;
    case ENUM_645_DATATYPE_INT64:
    case ENUM_645_DATATYPE_UNSIGNED_INT64:
    case ENUM_645_DATATYPE_DOUBLE:
        bytenum = 8;
        break;
    default:
    case ENUM_645_DATATYPE_CHAR:
    case ENUM_645_DATATYPE_UNSIGNED_CHAR:
        bytenum = 1;
        break;
    }

    if (pt->byte_Order == ENUM_645HEX_ORDER_LITTLE_ENDIAN){
        for (int i = 0; i < bytenum; i++)
        {
            bytedata[i] = pdata[i] - FLAG_ERRIDENT;
        }
    }
    else if (pt->byte_Order == ENUM_546HEX_ORDER_BIG_ENDIAN) {
        for (int i = 0; i < bytenum; i++)
        {
            bytedata[i] = pdata[bytenum - 1 - i] - FLAG_ERRIDENT;
        }
    }
    CLogger::getInstance()->log_d("get_decimal_value:rule_id=%lld,di=%s", pt->protocol_id, pt->di.c_str());
    OutputData("get_decimal_value", bytedata, bytenum);

    T value;
    if (pt->data_type == ENUM_645_DATATYPE_FLOAT)
    {
        float fval = 0;
        memcpy(&fval, bytedata, bytenum);
        value = fval;
    }
    else if (pt->data_type == ENUM_645_DATATYPE_DOUBLE)
    {
        double dfval = 0;
        memcpy(&dfval, bytedata, bytenum);
        value = dfval;
    }
    else{
        value = 0;
        for (int j = 0; j < bytenum; j++)
        {
            value += (bytedata[j] * (int)pow(256, j));
        }
    }

    return value;
}
template<typename T>
std::string CDlt645FrozenDataParseTask::get_final_val_ex(std::shared_ptr<DLT645_POINT> point, T value){
    if (nullptr == point){
        return "";
    }
    double v = 0.0f;
    char ret_buf[64] = { 0 };
    char str_format[32] = { 0 };
    if (point->formula.empty()){
        v = value * point->scale;
    }
    else {
        std::string formula = "echo \"" + point->formula + "\"|bc";
        std::stringstream fstr;
        fstr << value;

        formula = string_replace(formula, "X", fstr.str());
        if (0 == exec_cmd((char *)formula.c_str(), ret_buf, sizeof(ret_buf))){
            v = atof(ret_buf);
        }
    }
    if (0 < point->decimal){
        snprintf(str_format, sizeof(str_format), "%%.%dlf", point->decimal);
        snprintf(ret_buf, sizeof(ret_buf), str_format, v);
    }
    else {
        snprintf(ret_buf, sizeof(ret_buf), "%lf", v);
    }

    return ret_buf;
}

std::string CDlt645FrozenDataParseTask::get_hex_str(std::shared_ptr<DLT645_POINT> pt, uint8_t* pdata)
{
    std::string  val = "";
    if ((nullptr == pdata) || (nullptr == pt)){
        return val;
    }

    OutputData("get_hex_str", pdata, pt->data_size);

    uint8_t byteval = 0;
    char buf[8] = { 0 };
    for (int i = pt->data_size - 1; i >= 0; i--)
    {
        byteval = pdata[i] - FLAG_ERRIDENT;
        sprintf(buf, "%02x", byteval);
        val += buf;
    }
    return val;
}